
#include <BHBoxLayout>
#include <BVBoxLayout>
#include <BStyle>

#include "DrawLineStripeHandler.h"
#include "DrawLineStripeNote.h"

DrawLineStripeNote::DrawLineStripeNote(BWidget* parent) : Note(parent)
{
	this->setTitle("draw lines");
	_picker = 0;

	BHBoxLayout* modeLayout = new BHBoxLayout();
	{
		_drawRadioBox = new BRadioBox("Draw");
		_drawRadioBox->setAsset(OMode_Draw);

		_editRadioBox = new BRadioBox("Edit");
		_editRadioBox->setAsset(OMode_Edit);

		_pickRadioBox = new BRadioBox("Pick");
		_pickRadioBox->setAsset(OMode_Pick);

		modeLayout->addWidget(_drawRadioBox);
		modeLayout->addWidget(_editRadioBox);
		modeLayout->addWidget(_pickRadioBox);

		_modeButtonGroup = new BButtonGroup();
		_modeButtonGroup->addButton(_drawRadioBox);
		_modeButtonGroup->addButton(_editRadioBox);
		_modeButtonGroup->addButton(_pickRadioBox);

		modeLayout->setAsset(_modeButtonGroup);
		_drawRadioBox->setChecked(true);
	}

	BHBoxLayout* operateLayout = new BHBoxLayout();
	{
		_verticalButton = new BButton(Form_IconOnly);
		_verticalButton->setTips("Align Vertical");

		_horizontalButton = new BButton(Form_IconOnly);
		_horizontalButton->setTips("Align Horizontal");

		_uprightButton = new BButton(Form_IconOnly);
		_uprightButton->setTips("Align Upright");

		_adsorbPointButton = new BButton(Form_IconOnly);
		_adsorbPointButton->setTips("Adsorb polygon points");
		_adsorbPointButton->setCheckable(true);

		_adsorbMiddleButton = new BButton(Form_IconOnly);
		_adsorbMiddleButton->setTips("Adsorb middle of line");
		_adsorbMiddleButton->setCheckable(true);

		_adsorbCenterButton = new BButton(Form_IconOnly);
		_adsorbCenterButton->setTips("Adsorb polygon center");
		_adsorbCenterButton->setCheckable(true);

		operateLayout->addWidget(_verticalButton);
		operateLayout->addWidget(_horizontalButton);
		operateLayout->addWidget(_uprightButton);
		operateLayout->addSpacer(5);
		operateLayout->addWidget(_adsorbPointButton);
		operateLayout->addWidget(_adsorbMiddleButton);
		operateLayout->addWidget(_adsorbCenterButton);
	}

	BHBoxLayout* buttonLayout = new BHBoxLayout();
	{
		_okButton = new BButton("ok");
		_cancelButton = new BButton("cancel");
		_applyButton = new BButton("apply");
		buttonLayout->addWidget(_okButton);
		buttonLayout->addSpring();
		buttonLayout->addWidget(_cancelButton);
		buttonLayout->addWidget(_applyButton);
	}

	BVBoxLayout* vlayout = new BVBoxLayout(this);
	vlayout->addLayout(modeLayout);
	vlayout->addLayout(operateLayout);
	vlayout->addLayout(buttonLayout);

	connect(this, Signal_PropertyChanged, &DrawLineStripeNote::slotPropertyChanged);

	connect(_modeButtonGroup, Signal_Toggled, &DrawLineStripeNote::slotModeButtonToggled);
	connect(_verticalButton, Signal_Clicked, &DrawLineStripeNote::slotVerticalButtonClicked);
	connect(_horizontalButton, Signal_Clicked, &DrawLineStripeNote::slotHorizontalButtonClicked);
	connect(_uprightButton, Signal_Clicked, &DrawLineStripeNote::slotUprightButtonClicked);
	connect(_adsorbPointButton, Signal_Toggled, &DrawLineStripeNote::slotAdsorbPointButtonToggled);
	connect(_adsorbMiddleButton, Signal_Toggled, &DrawLineStripeNote::slotAdsorbMiddleButtonToggled);
	connect(_adsorbCenterButton, Signal_Toggled, &DrawLineStripeNote::slotAdsorbCenterButtonToggled);

	connect(_okButton, Signal_Clicked, &DrawLineStripeNote::slotOkButtonClicked);
	connect(_cancelButton, Signal_Clicked, &DrawLineStripeNote::slotCancelButtonClicked);
	connect(_applyButton, Signal_Clicked, &DrawLineStripeNote::slotApplyButtonClicked);
}
DrawLineStripeNote::~DrawLineStripeNote()
{

}

void DrawLineStripeNote::setOperaMode(OperaMode operaMode)
{
	if (BButton* button = _modeButtonGroup->buttonOfAsset(operaMode))
		button->setChecked(true);
}
DrawLineStripeNote::OperaMode DrawLineStripeNote::operaMode() const
{
	if (BButton* button = _modeButtonGroup->checkedButton())
		return button->asset();
	return OMode_None;
}

BSize DrawLineStripeNote::sizeHint() const
{
	return Note::sizeHint();
}

void DrawLineStripeNote::updateButtonStatus()
{
	bool enabled = false;
	if (_indices && _vertices)
	{
		if (_primitive == Primitive_Points && _indices->size() == 2)
		{
			enabled = true;
		}
		if (_primitive == Primitive_Lines && _indices->size() == 1)
		{
			enabled = true;
		}
	}
	_verticalButton->setEnabled(enabled);
	_horizontalButton->setEnabled(enabled);
	_uprightButton->setEnabled(enabled);
}

void DrawLineStripeNote::slotPropertyChanged(BObject* object, const BValue& value)
{
	const BString& name = value;
	if (name == "handler")
	{
		if (DrawLineStripeHandler* handler = this->property(name))
		{
			connect(handler, Signal_Changed, &DrawLineStripeNote::slotHandlerChanged);
		}
		return;
	}
	if (name == "picker")
	{
		_picker = this->property("picker");
		return;
	}
	if (name == "primitive")
	{
		_primitive = this->property(name);
		return;
	}
	if (name == "selected")
	{
		_indices = (BIntArray*)this->property(name);
		return;
	}
	if (name == "vertices")
	{
		_vertices = (BVectorArray*)this->property(name);
		return;
	}
}
void DrawLineStripeNote::slotModeButtonToggled(BObject* object, const BValue& value)
{
	if (value == _drawRadioBox)
	{
		_adsorbPointButton->setEnabled(true);
		_adsorbMiddleButton->setEnabled(true);
		_adsorbCenterButton->setEnabled(true);
	}
	if (value == _editRadioBox)
	{
		_adsorbPointButton->setEnabled(false);
		_adsorbMiddleButton->setEnabled(false);
		_adsorbCenterButton->setEnabled(false);
	}
	if (value == _pickRadioBox)
	{
		_adsorbPointButton->setEnabled(false);
		_adsorbMiddleButton->setEnabled(false);
		_adsorbCenterButton->setEnabled(false);
	}
	emit("mode-changed", operaMode());
}
void DrawLineStripeNote::slotVerticalButtonClicked(BObject* object, const BValue& value)
{
	if (_indices && _vertices)
	{
		if (_primitive == Primitive_Points && _indices->size() == 2)
		{
			BVector& v0 = (*_vertices)[_indices->at(0)];
			BVector& v1 = (*_vertices)[_indices->at(1)];
			v1.x() = v0.x();
			v1.z() = v0.z();
		}
		if (_primitive == Primitive_Lines && _indices->size() == 1)
		{
			BVector& v0 = (*_vertices)[_indices->at(0)];
			BVector& v1 = (*_vertices)[_indices->at(0) + 1];
			v1.x() = v0.x();
			v1.z() = v0.z();
		}
	}
}
void DrawLineStripeNote::slotHorizontalButtonClicked(BObject* object, const BValue& value)
{
	if (_indices && _vertices)
	{
		if (_primitive == Primitive_Points && _indices->size() == 2)
		{
			BVector& v0 = (*_vertices)[_indices->at(0)];
			BVector& v1 = (*_vertices)[_indices->at(1)];
			v1.y() = v0.y();
			v1.z() = v0.z();
		}
		if (_primitive == Primitive_Lines && _indices->size() == 1)
		{
			BVector& v0 = (*_vertices)[_indices->at(0)];
			BVector& v1 = (*_vertices)[_indices->at(0) + 1];
			v1.y() = v0.y();
			v1.z() = v0.z();
		}
	}
}
void DrawLineStripeNote::slotUprightButtonClicked(BObject* object, const BValue& value)
{
	if (_indices && _vertices)
	{
		if (_primitive == Primitive_Points && _indices->size() == 2)
		{
			BVector& v0 = (*_vertices)[_indices->at(0)];
			BVector& v1 = (*_vertices)[_indices->at(1)];
			v1.x() = v0.x();
			v1.y() = v0.y();
		}
		if (_primitive == Primitive_Lines && _indices->size() == 1)
		{
			BVector& v0 = (*_vertices)[_indices->at(0)];
			BVector& v1 = (*_vertices)[_indices->at(0) + 1];
			v1.x() = v0.x();
			v1.y() = v0.y();
		}
	}
}
void DrawLineStripeNote::slotAdsorbPointButtonToggled(BObject* object, const BValue& value)
{
	bool checked = value;
	_picker->setAdsorbPoint(checked);
}
void DrawLineStripeNote::slotAdsorbMiddleButtonToggled(BObject* object, const BValue& value)
{
	bool checked = value;
	_picker->setAdsorbLineMiddle(checked);
}
void DrawLineStripeNote::slotAdsorbCenterButtonToggled(BObject* object, const BValue& value)
{
	bool checked = value;
	_picker->setAdsorbPolygonCenter(checked);
}

void DrawLineStripeNote::slotHandlerChanged(BObject* object, const BValue& value)
{
	_okButton->setEnabled(true);
	_applyButton->setEnabled(true);
}
void DrawLineStripeNote::slotOkButtonClicked(BObject* object, const BValue& value)
{
	if (DrawLineStripeHandler* handler = this->property("handler"))
	{
		handler->applyChanges();
		this->post("remove-handler", handler);
	}
}
void DrawLineStripeNote::slotCancelButtonClicked(BObject* object, const BValue& value)
{
	if (DrawLineStripeHandler* handler = this->property("handler"))
	{
		handler->resetChanges();
		this->post("remove-handler", handler);
	}
}
void DrawLineStripeNote::slotApplyButtonClicked(BObject* object, const BValue& value)
{
	if (DrawLineStripeHandler* handler = this->property("handler"))
	{
		handler->applyChanges();
	}
}

void DrawLineStripeNote::showEvent(const BEvent& event)
{
	//if (Config* config = this->property("config"))
	//{
	//	_adsorbPointButton->setChecked(config->adsorbPoint());
	//	_adsorbMiddleButton->setChecked(config->adsorbMiddle());
	//	_adsorbCenterButton->setChecked(config->adsorbCenter());
	//}
}

void DrawLineStripeNote::styleEvent(const BEvent& event)
{
	if (const BStyle* style = this->realStyle())
	{
		_verticalButton->setIcon(style->icon("revise-vertical"));
		_horizontalButton->setIcon(style->icon("revise-horizontal"));
		_uprightButton->setIcon(style->icon("revise-upright"));
		_adsorbPointButton->setIcon(style->icon("absorb-point"));
		_adsorbMiddleButton->setIcon(style->icon("absorb-middle"));
		_adsorbCenterButton->setIcon(style->icon("absorb-center"));

		_okButton->setIcon(style->icon("ok"));
		_cancelButton->setIcon(style->icon("cancel"));
		_applyButton->setIcon(style->icon("apply"));
	}
}
